/*
 * UserPageTitledManageLabel.java
 *
 *
 */

package net.kernub.client;

import com.google.gwt.core.client.GWT;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;

import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;

import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.DialogBox;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyCodes;

import java.util.ArrayList;

import net.kernub.client.core.RPC;
import net.kernub.client.core.RPCCallback;
import net.kernub.client.core.datatype.CInteger;
import net.kernub.client.core.datatype.CBoolean;

import net.kernub.client.wwwConstants;
import net.kernub.client.PageTitled;
import net.kernub.client.LabelData;

import net.kernub.client.datatype.LabelDesc;
import net.kernub.client.datatype.LabelDescArray;

/*
 * UserPageTitledManageLabel class
 */
public class UserPageTitledManageLabel extends PageTitled
{
	private final wwwConstants constants = GWT.create( wwwConstants.class ); 

	private final VerticalPanel mainPanel = new VerticalPanel();
	private final FlexTable labelsTable = new FlexTable();

	private final ArrayList<LabelData> labelsList = new ArrayList<LabelData>();

	/*
	 * Edit DialogBox class
	 */
	private class EditDialogBox extends DialogBox
	{
		int id = -1;
		int row = -1;
		final TextBox nameTextBox = new TextBox();

		public EditDialogBox()
		{
			final Label nameLabel = new Label( constants.labelName() );
			final Button okButton = new Button( constants.ok() );
			final Button cancelButton = new Button( constants.cancel() );

			nameTextBox.setVisibleLength( 10 );
			nameTextBox.setMaxLength( 255 );
			nameTextBox.addStyleName( "LabelNameTextBox" );
			nameTextBox.addKeyPressHandler( new KeyPressHandler() {
				public void onKeyPress( KeyPressEvent event )
				{
					if( event.getCharCode() == KeyCodes.KEY_ENTER )
						okButton.click();
				}
			});

			okButton.addClickHandler( new ClickHandler() {
				public void onClick( ClickEvent event )
				{
					updateLabel();
				}
			});

			cancelButton.addClickHandler( new ClickHandler() {
				public void onClick( ClickEvent event )
				{
					nameTextBox.setText( "" );
					hide();
				}
			});

			final HorizontalPanel namePanel = new HorizontalPanel();
			namePanel.add( nameLabel );
			namePanel.add( nameTextBox );

			final HorizontalPanel buttonPanel = new HorizontalPanel();
			buttonPanel.setWidth( "100%" );
			buttonPanel.add( cancelButton );
			buttonPanel.add( okButton );
			buttonPanel.setCellHorizontalAlignment( cancelButton, HorizontalPanel.ALIGN_LEFT );
			buttonPanel.setCellHorizontalAlignment( okButton, HorizontalPanel.ALIGN_RIGHT );

			final VerticalPanel panel = new VerticalPanel();
			panel.add( namePanel );
			panel.add( buttonPanel );

			this.setText( constants.labelEditLabelTitle() );
			this.setWidget( panel );
		}

		public void setNameIDRow( String name, int id, int row )
		{
			this.nameTextBox.setText( name );
			this.id = id;
			this.row = row;
		}

		public void popup()
		{
			// set focus here, and select all
			this.center();
		}

		private void updateLabel()
		{
			if( nameTextBox.getText().isEmpty() )
				return;

			RPC.call( "site/Label", "update", this.id, nameTextBox.getText(), new RPCCallback<CBoolean>() {
				public void onCallback( CBoolean r )
				{
					if( !r.get() )
					{
						return;
					}

					final Label nameLabel = new Label( nameTextBox.getText() );
					nameLabel.addStyleName( "PageText" );

					labelsTable.setWidget( EditDialogBox.this.row, 0, nameLabel );

					nameTextBox.setText( "" );
					EditDialogBox.this.hide();
				}
			});
		}
	};

	private final EditDialogBox editDialogBox = new EditDialogBox();

	/*
	 * UserPageTitledManageLabel implementation
	 */

	public UserPageTitledManageLabel()
	{
		createNewLabelPart();
		createLabelListPart();
		createButtonsPart();

		mainPanel.setSpacing( 15 );
		mainPanel.setWidth( "100%" );

		setContent( mainPanel );
	}

	public void setActive()
	{
		super.setActive();

		this.setBigTitle( constants.labelMainTitle() );

		labelsList.clear();
		labelsTable.clear();
		int c = labelsTable.getRowCount();
		while( c > 0 ) labelsTable.removeRow( --c );

		updateList();
	}

	public void createNewLabelPart()
	{
		final Label titleLabel = new Label( constants.labelCreateNewLabel() );
		final Label nameLabel = new Label( constants.labelName() );
		final TextBox nameTextBox = new TextBox();
		final Button okButton = new Button( constants.ok() );

		titleLabel.addStyleName( "PageSubTitle" );

		nameLabel.addStyleName( "PageText" );

		nameTextBox.setVisibleLength( 10 );
		nameTextBox.setMaxLength( 255 );
		nameTextBox.addStyleName( "LabelNameTextBox" );
		nameTextBox.addKeyPressHandler( new KeyPressHandler() {
			public void onKeyPress( KeyPressEvent event )
			{
				if( event.getCharCode() == KeyCodes.KEY_ENTER )
					okButton.click();
			}
		});

		okButton.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				if( nameTextBox.getText().isEmpty() )
				{
					setTempInfo( constants.labelEmptyError() );
					return;
				}

				RPC.call( "site/Label", "add", nameTextBox.getText(), new RPCCallback<CInteger>() {
					public void onCallback( CInteger r )
					{
						if( r.get() < 0 )
						{
							setTempInfo( constants.labelAddError() );
							return;
						}
						addLabel( r.get(), nameTextBox.getText() );
						nameTextBox.setText( "" );
					}
				});

			}
		});

		final HorizontalPanel panel = new HorizontalPanel();
		panel.addStyleName( "PageSubContent" );
		panel.add( nameLabel );
		panel.add( nameTextBox );
		panel.add( okButton );

		mainPanel.add( titleLabel );
		mainPanel.add( panel );
	}

	public void createLabelListPart()
	{
		final Label titleLabel = new Label( constants.labelListTitle() );
		titleLabel.addStyleName( "PageSubTitle" );

		labelsList.clear();

		labelsTable.clear();
		labelsTable.addStyleName( "PageSubContent" );
		labelsTable.setWidth( "100%" );
		labelsTable.setCellSpacing( 5 );
		labelsTable.getColumnFormatter().setWidth( 0, "80%" );
		labelsTable.getColumnFormatter().setWidth( 1, "10%" );
		labelsTable.getColumnFormatter().setWidth( 2, "10%" );

		mainPanel.add( titleLabel );
		mainPanel.add( labelsTable );
	}

	public void createButtonsPart()
	{
		final Button okButton = new Button( constants.ok() );
		okButton.addStyleName( "PageText" );
		okButton.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				www.instance().setPage( www.PAGE_DISPLAY_LINKS );
			}
		});
	
		final HorizontalPanel panel = new HorizontalPanel();
		panel.setWidth( "100%" );
		panel.add( okButton );
		panel.setCellHorizontalAlignment( okButton, HorizontalPanel.ALIGN_CENTER );

		mainPanel.add( panel );
	}

	public void updateList()
	{
		DeferredCommand.addCommand( new Command() {
			public void execute()
			{
				RPC.call( "site/Label", "getList", new RPCCallback<LabelDescArray>() {
					public void onCallback( LabelDescArray r )
					{
						for( int i = 0; i < r.labels().length(); i++ )
						{
							addLabel( r.labels().get(i).getId(), r.labels().get(i).getName() );
						}
					}
				});
			}
		});
	}

	public void addLabel( final int id, final String name )
	{
		final int row = labelsTable.getRowCount();
		final LabelData label = new LabelData( id, name );
		final Label nameLabel = new Label( name );
		final Hyperlink editLink = new Hyperlink();

		labelsList.add( label );

		nameLabel.addStyleName( "PageText" );

		editLink.setText( constants.labelEditButton() );
		editLink.addStyleName( "LinkCursor" );
		editLink.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				editLabel( label );
			}
		});

		final Hyperlink removeLink = new Hyperlink();
		removeLink.setText( constants.labelRemoveButton() );
		removeLink.addStyleName( "LinkCursor" );
		removeLink.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				removeLabel( label );
			}
		});

		
		labelsTable.setWidget( row, 0, nameLabel );
		labelsTable.setWidget( row, 1, editLink );
		labelsTable.setWidget( row, 2, removeLink );
	}

	public void editLabel( final LabelData label )
	{
		int row = labelsList.indexOf( label );
		editDialogBox.setNameIDRow( label.getName(), label.getID(), row );
		editDialogBox.popup();
	}

	public void removeLabel( final LabelData label )
	{
		RPC.call( "site/Label", "remove", label.getID(), new RPCCallback<CBoolean>() {
			public void onCallback( CBoolean r )
			{
				if( r.get() )
				{
					int row = labelsList.indexOf( label );
					labelsList.remove( row );
					labelsTable.removeRow( row );
				}
				else
				{
					setTempInfo( constants.labelRemoveError() );
				}
			}
		});
	}


};

